package loginlog

import (
	"context"
	"devops-super/api/syslog/v1"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/gtime"
	"time"
)

// LoginLogLogic 登录日志逻辑实现
type LoginLogLogic struct{}

var cols = dao.SysLoginLog.Columns()

func init() {
	// 注册登录日志服务
	service.RegisterLoginLog(New())
}

// New 创建登录日志逻辑实例
func New() service.ILoginLog {
	return &LoginLogLogic{}
}

// GetPageLst 获取登录日志分页列表
func (l *LoginLogLogic) GetPageLst(ctx context.Context, req *v1.LoginGetPageLstReq) (res *v1.LoginGetPageLstRes, err error) {
	res = &v1.LoginGetPageLstRes{}
	m := dao.SysLoginLog.Ctx(ctx).Safe(true)

	// 按用户名筛选
	if req.UserName != "" {
		m = m.Where(cols.LoginName+" like ? ", "%"+req.UserName+"%")
	}

	// 按IP地址筛选
	if req.IpAddr != "" {
		m = m.Where(cols.Ipaddr+" like ? ", "%"+req.IpAddr+"%")
	}

	if req.TimeRange != nil {
		if len(req.TimeRange) != 2 {
			return nil, gerror.NewCode(gcode.CodeInvalidParameter, "时间范围参数格式错误")
		}
		// 新增时间转换逻辑
		startTime, err := time.Parse(time.RFC3339, req.TimeRange[0])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "开始时间格式错误")
		}
		endTime, err := time.Parse(time.RFC3339, req.TimeRange[1])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "结束时间格式错误")
		}
		timeLayout := "2006-01-02 15:04:05"
		timeStr0 := startTime.Local().Format(timeLayout)
		timeStr1 := endTime.Local().Format(timeLayout)
		m = m.WhereBetween("login_time", timeStr0, timeStr1)
	}
	// 默认按登录时间降序排序
	m = m.OrderDesc(cols.LoginTime)

	// 分页查询原始实体
	var entities []*entity.SysLoginLog
	if err = m.Offset(req.Offset()).Limit(req.Limit()).ScanAndCount(&entities, &res.Total, false); err != nil {
		return
	}

	// 转换为响应模型
	res.List = make([]*mymodel.LoginLogResponse, len(entities))
	for i, e := range entities {
		res.List[i] = &mymodel.LoginLogResponse{
			InfoId:        e.InfoId,
			LoginName:     e.LoginName,
			Ipaddr:        e.Ipaddr,
			LoginLocation: e.LoginLocation,
			Browser:       e.Browser,
			Os:            e.Os,
			Status:        e.Status,
			Msg:           e.Msg,
			LoginTime:     e.LoginTime,
		}
	}

	return
}

// GetOne 获取登录日志详情
func (l *LoginLogLogic) GetOne(ctx context.Context, infoId uint64) (data *entity.SysLoginLog, err error) {
	data = &entity.SysLoginLog{}
	err = dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().InfoId, infoId).Scan(data)
	if err != nil {
		return nil, err
	}
	return data, nil
}

// Add 添加登录日志
func (l *LoginLogLogic) Add(ctx context.Context, req *mymodel.LoginLog) (infoId uint64, err error) {
	// 手动构建实体，确保字段映射正确
	ent := &entity.SysLoginLog{
		LoginName:     req.UserName,
		Ipaddr:        req.IpAddr,
		LoginLocation: req.LoginLocation,
		Browser:       req.Browser,
		Os:            req.Os,
		Msg:           req.Msg,
		LoginTime:     gtime.Now(),
		Module:        "", // 默认值
		Status:        req.Status,
	}
	result, err := dao.SysLoginLog.Ctx(ctx).Data(ent).Insert()
	if err != nil {
		return 0, err
	}
	resId, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}
	return uint64(resId), nil
}

// Del 删除登录日志
func (l *LoginLogLogic) Del(ctx context.Context, infoId uint64) (rows int64, err error) {
	result, err := dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().InfoId, infoId).Delete()
	if err != nil {
		return 0, err
	}
	rows, err = result.RowsAffected()
	if err != nil {
		return 0, err
	}
	return rows, nil
}

// BatchDel 批量删除登录日志
func (l *LoginLogLogic) BatchDel(ctx context.Context, infoIds []uint64) (rows int64, err error) {
	if len(infoIds) == 0 {
		return 0, nil
	}
	result, err := dao.SysLoginLog.Ctx(ctx).WhereIn(dao.SysLoginLog.Columns().InfoId, infoIds).Delete()
	if err != nil {
		return 0, err
	}
	rows, err = result.RowsAffected()
	if err != nil {
		return 0, err
	}
	return rows, nil
}
